<template>
  <a-modal
    :visible="visible"
    width="580px"
    @cancel="handleCancel"
  >
    <template slot="title">
      导出数据<a-tag class="m-l-6">{{ $route.meta.title }}</a-tag>
    </template>
    <a-spin :spinning="spinning" tip="正在导出数据中...请耐心等待">
      <div class="checked">
        <a-checkbox
          :indeterminate="indeterminate"
          :checked="checkAll"
          @change="onCheckAllChange"
        >全选</a-checkbox>
      </div>
      <div class="checkbox-content">
        <draggable v-model="dragData" animation="300">
          <div class="checkbox-item" v-for="(item, index) in dragData" :key="index">
            <a-checkbox v-model="item.checked" @change="onChange">{{ item.title }}</a-checkbox>
            <a-icon type="bars"/>
          </div>
        </draggable>
      </div>
    </a-spin>
    <template slot="footer">
      <a-row type="flex" justify="start" align="middle">
        <a-col :span="12" style="text-align:left">
          <span style="color: #909399">提示：系统将导出勾选字段数据</span>
        </a-col>
        <a-col :span="12">
          <a-button type="plain" @click="handleCancel">取消</a-button>
          <a-button type="primary" @click="handleExport">确定</a-button>
        </a-col>
      </a-row>
    </template>
  </a-modal>
</template>

<script>
import { exportToExcel, formatJson } from '@/vendor/Export2Excel'
import draggable from 'vuedraggable'
export default {
  props: {
    visible: {
      type: Boolean,
      default: false
    },
    columns: {
      type: Array,
      default: () => []
    },
    request: {
      type: Function,
      required: true
    },
    filename: {
      type: String,
      default: ''
    }
  },
  components: {
    draggable
  },
  data () {
    return {
      spinning: false,
      indeterminate: false,
      checkAll: true,
      dragData: [],
      defaultData: []
    }
  },
  watch: {
    visible: function (newVal, oldVal) {
      if (newVal) {
        const result = []
        this.columns.forEach(item => {
          if (item.dataIndex) {
            result.push({ ...item, checked: true })
          }
        })
        this.dragData = result
        this.defaultData = result
      }
    }
  },
  methods: {
    onChange () {
      const checkedList = this.dragData.filter(value => value.checked)
      this.indeterminate = !!checkedList.length && checkedList.length < this.dragData.length
      this.checkAll = checkedList.length === this.dragData.length
    },
    onCheckAllChange (e) {
      const val = e.target.checked
      Object.assign(this, {
        indeterminate: false,
        checkAll: val,
        dragData: this.defaultData.map(value => ({ ...value, checked: val }))
      })
    },
    handleExport () {
      const fields = []
      const titles = []
      this.dragData.forEach(item => {
        if (item.checked) {
          fields.push(item.dataIndex)
          titles.push(item.title)
        }
      })
      if (!fields.length && !titles.length) {
        this.$message.error('请选择需要导出的字段数据')
        return
      }
      this.spinning = true
      this.request().then(res => {
        if (res.code === 200 && res.data.length > 0) {
          const header = titles
          const filterVal = fields
          const list = res.data
          const data = formatJson(filterVal, list)
          const filename = this.filename || this.$route.meta.title
          this.$message.success('导出数据成功')
          exportToExcel({
            header,
            data,
            filename
          })
          this.handleCancel()
        } else {
          this.$message.error(res.msg || '导出失败')
        }
      }).catch(err => {
        this.$message.error(`${err.response.statusText || '请检查网络状态或稍后重试'}， 状态码: ${err.response.status || 0}`)
      }).finally(() => {
        setTimeout(() => {
          this.spinning = false
        }, 1000)
      })
    },
    handleCancel () {
      this.$emit('cancel')
      this.dragData = []
      this.defaultData = []
      this.checkAll = true
      this.indeterminate = false
      this.spinning = false
    }
  }
}
</script>

<style lang="less" scoped>
  .checked {
    background-color: #F6F7FB;
    padding: 12px 10px;
  }
  .checkbox-content {
    height: 400px;
    overflow: auto;
    .checkbox-item {
      padding: 10px;
      border-bottom: 1px solid #e8e8e8;
      display: flex;
      justify-content: space-between;
      align-items: center;
      cursor: move;
    }
  }
</style>
